package wiki.hitime.stl.daq.service.task;

import wiki.hitime.stl.daq.bean.db.DaqMsgRule;
import wiki.hitime.stl.daq.enums.MsgTypeEnum;
import wiki.hitime.stl.daq.manager.*;
import wiki.hitime.stl.daq.manager.*;
import wiki.hitime.stl.daq.service.factory.DataMsgFactory;
import wiki.hitime.stl.daq.support.ContextHolder;
import groovy.text.SimpleTemplateEngine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.io.IOException;
import java.util.Map;

/**
 * @author zhangdaoping
 * @create 2019-07-16 20:42
 */
@Service
@Slf4j
public class DataMsgService {

    private DaqMsgRuleManager daqMsgRuleManager;
    private DaqMsgRecordManager daqMsgRecordManager;
    private DaqMsgRuleDetailConfigManager daqMsgRuleDetailConfigManager;
    private DaqMsgBaseConfigManager daqMsgBaseConfigManager;
    private DataMsgParamManager dataMsgParamManager;

    public DataMsgService(DaqMsgRuleManager daqMsgRuleManager,
                          DaqMsgRecordManager daqMsgRecordManager,
                          DaqMsgRuleDetailConfigManager daqMsgRuleDetailConfigManager,
                          DaqMsgBaseConfigManager daqMsgBaseConfigManager,
                          DataMsgParamManager dataMsgParamManager) {
        this.daqMsgRuleManager = daqMsgRuleManager;
        this.daqMsgRecordManager = daqMsgRecordManager;
        this.daqMsgRuleDetailConfigManager = daqMsgRuleDetailConfigManager;
        this.daqMsgBaseConfigManager = daqMsgBaseConfigManager;
        this.dataMsgParamManager = dataMsgParamManager;
    }

    /**
     * 消息通知
     *
     * @param executeRuleId 执行规则编号
     * @param checkRuleId   检查规则编号
     * @param checkRecordId 检查记录编号
     */
    public void notifyMsg(Long executeRuleId, Long checkRuleId, Long checkRecordId) {
        // 根据检查规则id获取消息通知规则
        DaqMsgRule msgRule = daqMsgRuleManager.loadRule(checkRuleId);
        if (msgRule == null) {
            return;
        }
        // 根据通知变量和模板加载通知内容
        String msgContent = "";
        try {
            msgContent = this.loadMsgContent(checkRecordId, msgRule.getMsgTemplate());
        } catch (Exception e) {
            log.error("加载消息通知内容异常，msgRuleId={}", msgRule.getId(), e);
        }
        // 新增消息通知记录
        Long msgRecordId = daqMsgRecordManager.addNotProcessRecord(executeRuleId, msgRule, checkRecordId, msgContent);
        try {
            // 根据消息通知规则获取通知配置信息
            Map<String, String> baseConfigMap = daqMsgBaseConfigManager.loadMsgBaseConfig(msgRule.getMsgType());
            Map<String, String> msgRuleDetailConfigMap = daqMsgRuleDetailConfigManager.loadMsgRuleDetailConfig(msgRule.getId());
            // 根据通知类型和通知配置进行通知
            DataMsgFactory dataMsgFactory = loadImplService(msgRule.getMsgType());
            Assert.notNull(dataMsgFactory, "消息实现服务为空");
            Boolean msgResult = dataMsgFactory.notifyMsg(msgRule.getMsgReceiver(), msgContent, baseConfigMap, msgRuleDetailConfigMap);
            if (msgResult) {
                // 更新消息通知记录状态
                daqMsgRecordManager.updateProcessSucceed(msgRecordId);
            } else {
                // 更新消息通知记录状态
                daqMsgRecordManager.updateProcessFailed(msgRecordId, "通知渠道返回未成功");
            }
        } catch (Exception e) {
            log.error("消息通知异常，executeRuleId={}", executeRuleId);
            // 更新消息通知记录状态
            daqMsgRecordManager.updateProcessFailed(msgRecordId, e.getMessage());
        }
    }

    public void notfiyWaiting() {
        // 查询未通知成功的消息记录

        // 根据消息通知规则和消息内容再次通知
    }


    /**
     * 加载消息内容
     *
     * @param msgTemplate 消息模板
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    private String loadMsgContent(Long checkRecordId, String msgTemplate) throws IOException, ClassNotFoundException {
        // 解析模板
        SimpleTemplateEngine simpleTemplateEngine = new SimpleTemplateEngine();
        return simpleTemplateEngine.createTemplate(msgTemplate).make(dataMsgParamManager.loadMsgParams(checkRecordId)).toString();
    }

    /**
     * 加载实现服务
     *
     * @param msgType
     * @return
     */
    private DataMsgFactory loadImplService(Integer msgType) {
        MsgTypeEnum msgTypeEnum = MsgTypeEnum.valueOf(msgType);
        Assert.notNull(msgTypeEnum, "消息类型为空");
        Map<String, DataMsgFactory> objectMap = ContextHolder.getBeanOfType(DataMsgFactory.class);
        for (Map.Entry entry : objectMap.entrySet()) {
            DataMsgFactory factory = (DataMsgFactory) entry.getValue();
            if (factory.getSupportMsgType().equals(msgTypeEnum)) {
                return factory;
            }
        }
        return null;
    }
}
